
package com.wyh.service.serviceImpl.groupOne.contractManagement;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wyh.common.enums.ResultCodeEnum;
import com.wyh.common.exception.CustomException;
import com.wyh.common.result.Result;

import com.wyh.domain.po.groupOne.contractManagement.*;
import com.wyh.domain.po.groupOne.threemeterAbout.Threemeter;
import com.wyh.domain.po.groupOne.titleReview.MasterDataCustomer;

import com.wyh.domain.vo.groupOne.customer.MasterDataCustomerVO;
import com.wyh.domain.vo.groupOne.contractManagement.*;
import com.wyh.mapper.groupOne.contractManagement.MasterDataContractMapper;
import com.wyh.mapper.groupOne.contractManagement.MasterDataContractitemMapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyh.service.groupOne.customer.MasterDataCCustomerService;
import com.wyh.service.groupOne.contractManagement.*;
import com.wyh.service.groupOne.threemeterAbout.threemeterTable.MasterDataIThreemeterTableService;
import com.wyh.service.groupOne.titleReview.MasterDataICustomerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.wyh.common.enums.ResultCodeEnum.INPUT_RULE_ERROR;

/**
 * <p>
 * 合同表 服务实现类
 * </p>
 *
 * @author lsf
 * @since 2024-06-03
 */
@Service
@Slf4j
public class MasterDataContractServiceImplMasterData extends ServiceImpl<MasterDataContractMapper, MasterDataContract> implements MasterDataIContractService {
    @Autowired
    private MasterDataICustomerService customerService;

    @Autowired
    private MasterDataIBuildingunitsService buildingunitsService;

    @Autowired
    private MasterDataIContractitemService contractitemService;

    @Autowired
    private MasterDataIFormulaService formulaService;

    @Autowired
    private MasterDataIThreemeterTableService threemeterTableService;

    @Autowired
    private MasterDataContractMapper masterDataContractMapper;

    @Autowired
    private MasterDataContractitemMapper masterDataContractitemMapper;

    @Autowired
    private MasterDataIResourceService resourceService;

    @Autowired
    private MasterDataCCustomerService ccustomerServiceMasterData;
    /**
     * 条件分页查询合同
     * @param masterDataContractVO
     * @return
     */
    @Override
    public Result<List<MasterDataContractVO>> contractList(MasterDataContractVO masterDataContractVO) {

        //获取客户Id和客户姓名
        QueryWrapper<MasterDataCustomer> customerQueryWrapper= new QueryWrapper<>();
        customerQueryWrapper.select("id","name","telephone");
        int customerQueryLog=0;
        if (masterDataContractVO.getCustomerName()!=null&& masterDataContractVO.getCustomerName().length()>0){
            customerQueryWrapper.like("name", masterDataContractVO.getCustomerName());
            customerQueryLog++;
        }
        if (masterDataContractVO.getTelephone()!=null && masterDataContractVO.getTelephone().length()>0){
            customerQueryWrapper.like("telephone", masterDataContractVO.getTelephone());
            customerQueryLog++;
        }

        List<MasterDataCustomer> masterDataCustomerList =null;
        List<Integer> customerIdList =null;
        if (customerQueryLog>0){
            masterDataCustomerList = customerService.list(customerQueryWrapper);
            customerIdList = masterDataCustomerList.stream()
                    .map(MasterDataCustomer::getId)
                    .collect(Collectors.toList());
        }
        log.info("customerQueryWrapper:{}",customerQueryWrapper);
        //获取资源id
        List<Buildingunits> buildingunitsList =null;
        List<Integer> buildingunitsIdList=null;
        if (masterDataContractVO.getBuildingunitsName()!=null&& masterDataContractVO.getBuildingunitsName().length()>0){
            QueryWrapper<Buildingunits> buildingunitsQueryWrapper=new QueryWrapper<Buildingunits>();
            buildingunitsQueryWrapper.select("id","name").like("name", masterDataContractVO.getBuildingunitsName());
           buildingunitsList = buildingunitsService.list(buildingunitsQueryWrapper);
            buildingunitsIdList = buildingunitsList.stream()
                    .map(Buildingunits::getId)
                    .collect(Collectors.toList());
        }
        log.info("buildingunitsIdList:{}",buildingunitsIdList);

        //分页条件查询合同表
        QueryWrapper<MasterDataContract> contractQueryWrapper=new QueryWrapper<MasterDataContract>();
        //String转LocalTime
        DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        try {
            if (masterDataContractVO.getLeftTime()!=null&& masterDataContractVO.getLeftTime().length()>0){
                contractQueryWrapper.ge("generationtime", LocalDateTime.parse(masterDataContractVO.getLeftTime(),localDateTimeFormatter));

            }
            if (masterDataContractVO.getRightTime()!=null&& masterDataContractVO.getRightTime().length()>0){
                contractQueryWrapper.le("generationtime",LocalDateTime.parse(masterDataContractVO.getRightTime(),localDateTimeFormatter));
            }
        }
        catch (Exception e){
            return Result.error(INPUT_RULE_ERROR);
        }

        if ((customerQueryLog>0)&&masterDataCustomerList !=null&& masterDataCustomerList.size()>0){
            contractQueryWrapper.in("customerid",customerIdList);
        }
        if (masterDataContractVO.getState()!=null){
            contractQueryWrapper.eq("state", masterDataContractVO.getState());
        }
        if (masterDataContractVO.getContractnumber()!=null&& masterDataContractVO.getContractnumber().length()>0){
            contractQueryWrapper.like("contractnumber", masterDataContractVO.getContractnumber());
        }
        if (buildingunitsIdList!=null&&buildingunitsIdList.size()>0){
            contractQueryWrapper.in("resourceid",buildingunitsIdList);
        }
        if (masterDataContractVO.getRole()!=null){
            contractQueryWrapper.eq("role", masterDataContractVO.getRole());
        }
        contractQueryWrapper.orderByDesc("generationtime");
        Page<MasterDataContract> contractPageList=page(new Page<>(masterDataContractVO.getCurrentPage(), masterDataContractVO.getSize()),contractQueryWrapper);
        log.info("contractPageList:{}",contractPageList);

        if (contractPageList!=null){
            List<MasterDataContract> masterDataContractList =contractPageList.getRecords();
            System.out.println("masterDataContractList："+ masterDataContractList);
            List<MasterDataContractVO> masterDataContractVOList =new ArrayList<>();
            for (int i = 0; i< masterDataContractList.size(); i++){
                MasterDataContractVO masterDataContractVOCopy =new MasterDataContractVO();
                BeanUtils.copyProperties(masterDataContractList.get(i), masterDataContractVOCopy);
                masterDataContractVOCopy.setGenerationtime(String.valueOf(masterDataContractList.get(i).getGenerationtime()));
                /**
                 * 二分查找name和Telephone插入contractVOList
                 */
                if (masterDataCustomerList!=null&&masterDataCustomerList.size()>0) {
                    for (int low = 0, high = masterDataCustomerList.size() - 1; low <= high; ) {
                        int mid = (low + high) / 2;
                        if (Objects.equals(masterDataContractList.get(i).getCustomerid(), masterDataCustomerList.get(mid).getId())) {
                            masterDataContractVOCopy.setCustomerName(masterDataCustomerList.get(mid).getName());
                            masterDataContractVOCopy.setTelephone(masterDataCustomerList.get(mid).getTelephone());

                            break;
                        } else if (masterDataCustomerList.get(mid).getId() > masterDataContractList.get(i).getCustomerid()) {
                            high = mid - 1;

                        } else {
                            low = mid + 1;

                        }

                    }
                }

                /**
                 * 二分查找资源名称插入contractVOList
                 */
                if (buildingunitsList!=null&&buildingunitsList.size()>0) {
                    for (int lowb = 0, highb = buildingunitsList.size() - 1; lowb <= highb; ) {
                        int midb = (lowb + highb) / 2;
                        System.out.println(0);
                        if (Objects.equals(masterDataContractList.get(i).getResourceid(), buildingunitsList.get(midb).getId())) {
                            masterDataContractVOCopy.setBuildingunitsName(buildingunitsList.get(midb).getName());
                            System.out.println(1);

                            break;
                        } else if (buildingunitsList.get(midb).getId() > masterDataContractList.get(i).getResourceid()) {
                            highb = midb - 1;
                            System.out.println(2);

                        } else {
                            lowb = midb + 1;
                            System.out.println(3);

                        }

                    }
                }

//                if (masterDataContractVOCopy.getCustomerName()==null || masterDataContractVOCopy.getTelephone()==null || masterDataContractVOCopy.getBuildingunitsName()==null ){
//                    throw new CustomException(INPUT_RULE_ERROR);
//                }
                masterDataContractVOCopy.setTotal(contractPageList.getTotal());
                masterDataContractVOList.add(masterDataContractVOCopy);
            }
            return Result.success(masterDataContractVOList);
        }


        return Result.success();
    }


    /**
     * 详情页
     * @param contractId
     *
     */

    @Override
    public Result<ContractDetailsVO> getContractDetails(Integer contractId) {
        ContractDetailsVO contractDetailsVO=new ContractDetailsVO();
        //查询合同表信息
        MasterDataContract masterDataContractById = getById(contractId);

        //查询客户表
        MasterDataCustomer masterDataCustomerById = customerService.getById(masterDataContractById.getCustomerid());

        //计费配置
        QueryWrapper<Contractitem> contractitemQueryWrapper=new QueryWrapper<>();
        contractitemQueryWrapper.eq("contractid",contractId);
        List<Contractitem> contractitemList = contractitemService.list(contractitemQueryWrapper);
        List<ContractitemVO> contractItemVOList = contractitemList.stream()
                .map(contractItem -> new ContractitemVO(
                        contractItem.getId(),
                        contractItem.getName(),
                        contractItem.getMethod(),
                        contractItem.getPrice(),
                        contractItem.getStarttime(),
                        contractItem.getInitialreading()
                ))
                .collect(Collectors.toList());



        //计费公式
        QueryWrapper<Formula> formulaQueryWrapper=new QueryWrapper<>();
        List<Integer> formulId=new ArrayList<>();

        formulId = contractitemList.stream()
                .map(Contractitem::getMethod)
                .collect(Collectors.toList());
        if (formulId!=null&&formulId.size()>0) {
            formulaQueryWrapper.in("id", formulId);
        }
        formulaQueryWrapper.select("id",  "formula");
        List<Formula> formulaList = formulaService.list(formulaQueryWrapper);
        for (int i = 0; i < contractitemList.size(); i++) {
            for (int j = 0; j < formulaList.size(); j++) {
                if (contractitemList.get(i).getFormula()==formulaList.get(j).getId()){
                    contractItemVOList.get(i).setFormula(formulaList.get(j).getFormula());
                    break;
                }
                else if (j==(formulaList.size()-1)){
                    throw new CustomException(INPUT_RULE_ERROR);
                }
            }

        }

        log.info("formulaList{}",formulaList);

        //三表名称
        QueryWrapper<Threemeter> threemeterQueryWrapper=new QueryWrapper<>();
        List<Integer> meterid=new ArrayList<>();
        meterid=contractitemList.stream()
                .map(Contractitem::getMeterid)
                .collect(Collectors.toList());
        if (meterid!=null&&meterid.size()>0) {
            threemeterQueryWrapper.in("id", meterid);
        }
        threemeterQueryWrapper.select("id","name");
        List<Threemeter> threemeterList = threemeterTableService.list(threemeterQueryWrapper);
        for (int i = 0; i < contractitemList.size(); i++) {
            for (int j = 0; j < threemeterList.size(); j++) {
                if (contractitemList.get(i).getMeterid()==threemeterList.get(j).getId()){
                    contractItemVOList.get(i).setMeterName(threemeterList.get(j).getName());
                    break;
                }
                else if(j==(threemeterList.size()-1)){
                    throw new CustomException(INPUT_RULE_ERROR);

                }
            }
        }

        log.info("threemeterList{}",threemeterList);

        //资源查询
        MasterDataResource_1 resourceById = resourceService.getById(masterDataContractById.getResourceid());
        log.info("resourceById{}",resourceById);
        //数据封装
        BeanUtils.copyProperties(masterDataContractById,contractDetailsVO);
        if (masterDataCustomerById.getName()!=null && masterDataCustomerById.getName().length()>0) {
            contractDetailsVO.setCustomerName(masterDataCustomerById.getName());
        }
        if (resourceById.getInfoname()!=null&&resourceById.getInfoname().length()>0) {
            contractDetailsVO.setBuildingunitsName(resourceById.getInfoname());
        }
        contractDetailsVO.setContractitemVOList(contractItemVOList);
        log.info("contractDetailsVO:{}",contractDetailsVO);

        return Result.success(contractDetailsVO);
    }



    /**
     * 详情页编辑
     * @param contractChangeVO
     *
     */
    @Override
    public Result changeContract(ContractChangeVO contractChangeVO) {

        //查询合同状态是否可编辑
        if (checkState(contractChangeVO.getId())){
            return Result.error("该合同已作废，无法编辑");
        }

        //contract合同表修改
        MasterDataContract masterDataContractChange =new MasterDataContract();
        BeanUtils.copyProperties(contractChangeVO, masterDataContractChange);
        masterDataContractChange.setUpdatetime(LocalDateTime.now());
        int contractChangeNum = masterDataContractMapper.updateById(masterDataContractChange);
        log.info("已修改{}条",contractChangeNum);

        //ContractitemList删除

        if (contractChangeVO.getWillDeletedContractitemIdList()!=null) {
            List<Integer> willDeletedContractitemIdList = contractChangeVO.getWillDeletedContractitemIdList();
            UpdateWrapper<Contractitem> contractitemUpdateWrapper = new UpdateWrapper<>();
            contractitemUpdateWrapper.eq("contractid", contractChangeVO.getId())
                    .in("id", willDeletedContractitemIdList)
                    .set("state",-1);
            boolean updateResult = contractitemService.update(contractitemUpdateWrapper);
        }


        //新增费项List

        DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        if (contractChangeVO.getNewContractitemList()!=null) {
            List<ContractitemListVO> newContractitemList = contractChangeVO.getNewContractitemList();
            List<Contractitem> contractitemList=new ArrayList<>();

            for (int i = 0; i < newContractitemList.size(); i++) {
                Contractitem contractitem=new Contractitem();
                BeanUtils.copyProperties(newContractitemList.get(i),contractitem);
                contractitem.setStarttime(LocalDateTime.parse(newContractitemList.get(i).getStarttime(),localDateTimeFormatter));
                contractitem.setContractid(contractChangeVO.getId());
                contractitem.setState(1);
                contractitemList.add(contractitem);
            }

            if (!contractitemService.saveBatch(contractitemList, 3)){
                return Result.error(ResultCodeEnum.PARAM_ERROR);
            }


        }
        return Result.success("修改成功");
    }


    /**
     * 作废合同
     * @param id
     * @return
     */
    @Override
    public Result cancleContract(Integer id) {
        if (checkState(id)){
            return Result.error("该合同已作废，无法作废");
        }
        UpdateWrapper<MasterDataContract> contractUpdateWrapper=new UpdateWrapper<>();
        contractUpdateWrapper.eq("id",id);
        contractUpdateWrapper.set("updatetime",LocalDateTime.now()).set("expirationtime",LocalDateTime.now());
        contractUpdateWrapper.set("state",0).set("failurereason","作废");
        if (update(contractUpdateWrapper)){
            return Result.success("作废成功");
        }
        return Result.error("作废失败 ");
    }

    /**
     * 新增合同
     * @param contractAddVO
     * @return
     */
    @Override
    public Result addContract(ContractAddVO contractAddVO) {

        //资源状态查询

        MasterDataResource_1 masterDataResource1ById = resourceService.getById(contractAddVO.getResourceid());
        if (masterDataResource1ById ==null){
            return Result.error("没有该资源");
        }
        Integer resourceState = masterDataResource1ById.getState();

        //资源修改构建
        UpdateWrapper<MasterDataResource_1> resourceUpdateWrapper=new UpdateWrapper<>();

        //角色为业主
        if (contractAddVO.getRole()==0&&resourceState==0){
            //未接房

                resourceUpdateWrapper.set("state",1);


        } else if (contractAddVO.getRole()==1) {
            if (resourceState==0){
                return Result.error("该资源无业主，无法迁入租户");
            }
            else if (resourceState==1){
                resourceUpdateWrapper.set("state",2);
            } else if (resourceState==2) {

                return Result.error("该资源已出租，无法迁入新租户");
            }
        }else if (resourceState==3) {
            //已停用
            return Result.error(ResultCodeEnum.PARAM_ERROR);
        }



        //合同表插入
        MasterDataContract masterDataContract =new MasterDataContract();
        BeanUtils.copyProperties(contractAddVO, masterDataContract);
        masterDataContract.setGenerationtime(LocalDateTime.now());
        masterDataContract.setUpdatetime(LocalDateTime.now());
        masterDataContract.setState(1);
        if (contractAddVO.getNewContractitemList()!=null&&contractAddVO.getNewContractitemList().size()>0){
            save(masterDataContract);
        }
        else {
            return Result.error("至少选择一个计费项目");
        }

        //获取费项List
        List<ContractitemListVO> newContractitemList = contractAddVO.getNewContractitemList();
        List<Contractitem> contractitemList=new ArrayList<>();
        DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        for (int i = 0; i < newContractitemList.size(); i++) {
            Contractitem contractIterator=new Contractitem();
            BeanUtils.copyProperties(newContractitemList.get(i),contractIterator);
            contractIterator.setStarttime(LocalDateTime.parse(newContractitemList.get(i).getStarttime(),localDateTimeFormatter));
            contractIterator.setContractid(masterDataContract.getId());
            contractIterator.setState(1);
            contractitemList.add(contractIterator);
        }
        contractitemService.saveBatch(contractitemList,contractitemList.size());
        log.info("contractitemList:{}",contractitemList);
        return Result.success();
    }

    /**
     * 获取新增合同时客户列表
     * @param input
     * @return
     */
    @Override
    public Result<List<MasterDataCustomerVO>> getCustomer(String input) {
        return Result.success(ccustomerServiceMasterData.selectByOther(input));
    }


    /**
     //查询合同状态是否可编辑
     * state==0,return true
     * @param id
     * @return
     */
    private boolean checkState(Integer id){
        MasterDataContract masterDataContract = masterDataContractMapper.selectById(id);
        if (masterDataContract.getState()==0){
            return true;
        }
        return false;
    }

}
